import 'dart:io';

import 'package:dio/dio.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter/material.dart';
import 'package:tupgrade/app_upgrade.dart';
import 'package:tupgrade/tupgrade.dart';

///
/// des:app升级提示控件
///
class SimpleAppUpgradeWidget extends StatefulWidget {
  const SimpleAppUpgradeWidget({Key? key, required this.title,
      this.titleStyle,
      required this.contents,
      this.contentStyle,
      required this.cancelText,
      this.cancelTextStyle,
      required this.okText,
      this.okTextStyle,
      this.progressBar,
      required this.downloadUrl,
      required this.downloadApkName,
      this.force = false,
      this.onCancel,
      this.onOk,
      this.downloadProgress,
      this.downloadStatusChange}):super(key: key);

  ///
  /// 升级标题
  ///
  final String title;

  ///
  /// 标题样式
  ///
  final TextStyle? titleStyle;

  ///
  /// 升级提示内容
  ///
  final List<String> contents;

  ///
  /// 提示内容样式
  ///
  final TextStyle? contentStyle;

  ///
  /// 下载进度条
  ///
  final Widget? progressBar;

  ///
  /// 确认控件
  ///
  final String okText;

  ///
  /// 确认控件样式
  ///
  final TextStyle? okTextStyle;

  ///
  /// 取消控件
  ///
  final String cancelText;

  ///
  /// 取消控件样式
  ///
  final TextStyle? cancelTextStyle;

  ///
  /// app安装包下载url,没有下载跳转到应用宝等渠道更新
  ///
  final String downloadUrl;
  final String downloadApkName;

  ///
  /// 是否强制升级,设置true没有取消按钮
  ///
  final bool force;


  final VoidCallback? onCancel;
  final VoidCallback? onOk;
  final DownloadProgressCallback? downloadProgress;
  final DownloadStatusChangeCallback? downloadStatusChange;

  @override
  State<StatefulWidget> createState() => _SimpleAppUpgradeWidget();
}

class _SimpleAppUpgradeWidget extends State<SimpleAppUpgradeWidget> {
  ///
  /// 下载进度
  ///
  double _downloadProgress = 0.0;

  DownloadStatus _downloadStatus = DownloadStatus.none;

  @override
  Widget build(BuildContext context) {
    return Container(
      child: _buildInfoWidget(context),
    );
  }

  ///
  /// 信息展示widget
  ///
  Widget _buildInfoWidget(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        //标题
        _buildTitle(),
        //更新信息
        _buildAppInfo(),
        Offstage(offstage: _downloadProgress <= 0, child: _buildDownloadProgress(),),
        //操作按钮
        AbsorbPointer(absorbing: _downloadStatus != DownloadStatus.none && _downloadStatus != DownloadStatus.error,
        child: _buildAction(),),
      ],
    );
  }

  ///
  /// 构建标题
  ///
  _buildTitle() {
    return Padding(
        padding: const EdgeInsets.only(top: 20, bottom: 30),
        child: Text(widget.title,
            style: widget.titleStyle ?? const TextStyle(fontSize: 22)));
  }

  ///
  /// 构建版本更新信息
  ///
  _buildAppInfo() {
    return Container(
        padding: const EdgeInsets.only(left: 15, right: 15, bottom: 30),
        constraints: const BoxConstraints(minHeight: 80),
        child: ListView(
          shrinkWrap: true,
          children: widget.contents.map((f) {
            return Text(
              f,
              style: widget.contentStyle ?? const TextStyle(),
            );
          }).toList(),
        ));
  }

  ///
  /// 构建取消或者升级按钮
  ///
  _buildAction() {
    return Column(
      children: <Widget>[
        const Divider(
          height: 1,
          color: Colors.grey,
        ),
        Padding(padding: const EdgeInsets.only(right: 15),child: 
        Row(
          mainAxisAlignment: MainAxisAlignment.end,
          children: <Widget>[
            Offstage(offstage: widget.force, child: _buildCancelActionButton(),),
            _buildOkActionButton(),
          ],
        ),),
      ],
    );
  }

  ///
  /// 取消按钮
  ///
  _buildCancelActionButton() {
    return TextButton(onPressed: (){
      widget.onCancel?.call();
      Navigator.of(context).pop();
    }, child: Text(widget.cancelText,
              style: widget.okTextStyle ?? const TextStyle(color: Color(0xff8c8c8c))));
  
  }

  ///
  /// 确定按钮
  ///
  _buildOkActionButton() {
    return TextButton(onPressed: (){
      _clickOk();
    }, 
    child: Text(widget.okText,
              style: widget.okTextStyle ?? const TextStyle(color: Color(0xFF1948A6))));
  }

  ///
  /// 下载进度widget
  ///
  Widget _buildDownloadProgress() {
    return LinearProgressIndicator(
      minHeight: 2,
      value: _downloadProgress,
      valueColor: const AlwaysStoppedAnimation<Color>(Color(0xFF1948A6)),
     backgroundColor: const Color(0xff8c8c8c),
    );
  }

  ///
  /// 点击确定按钮
  ///
  _clickOk() async {
    widget.onOk?.call();
    if (Platform.isIOS) {
      Navigator.pop(context);
      //ios 需要跳转到app store更新，原生实现
      Tupgrade.toAppStore(widget.downloadUrl);
      return;
    }
    Directory? storageDir = await getExternalStorageDirectory();
    String storagePath = storageDir!.path;
    _downloadApk(widget.downloadUrl, '$storagePath/${widget.downloadApkName}');
  }

  ///
  /// 下载apk包
  ///
  _downloadApk(String url, String path) async {
    if (_downloadStatus == DownloadStatus.start ||
        _downloadStatus == DownloadStatus.downloading ||
        _downloadStatus == DownloadStatus.done) {
      print('当前下载状态：$_downloadStatus,不能重复下载。');
      return;
    }

    _updateDownloadStatus(DownloadStatus.start);
    try {
      var dio = Dio();
      await dio.download(url, path, onReceiveProgress: (int count, int total) {
        if (total == -1) {
          _downloadProgress = 0.01;
        } else {
          widget.downloadProgress?.call(count, total);
          _downloadProgress = count / total.toDouble();
        }
        setState(() {});
        if (_downloadProgress == 1) {
          //下载完成，跳转到程序安装界面
          _updateDownloadStatus(DownloadStatus.done);
          print("path:" + path);
          Navigator.pop(context);
          Tupgrade.installAppForAndroid(path);
        }
      });
    } catch (e) {
      print('$e');
      _downloadProgress = 0;
      _updateDownloadStatus(DownloadStatus.error,error: e);
    }
  }

  _updateDownloadStatus(DownloadStatus downloadStatus, {dynamic error}) {
    _downloadStatus = downloadStatus;
    widget.downloadStatusChange?.call(_downloadStatus, error: error);
  }
}
